//
// Copyright (c) 2009 All Right Reserved
//
// vl
//
// 2018-12-01
// Contains ...
using JetBrains.Annotations;
using LargoCommon.Interfaces;
using LargoCommon.Midi;
using LargoCommon.Music;
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
namespace LargoPanels.Editor
{
/// A base chart master.
public partial class EditorSpace : FrameworkElement, IEditorSpace
{
#region Fields - readonly
///
/// The delta vertical scroll
///
public readonly int DeltaVerticalScroll = 10;
///
/// The delta horizontal scroll
///
public readonly int DeltaHorizontalScroll = 20;
/// The left space.
public readonly int LeftSpace = 50;
/// The top space.
public readonly int TopSpace = 40; //// 10
/// Margin on the right.
public int MaxLeft; //// = 45 /*50 LeftSpace*/ + 14 * SeedSize.CurrentWidth; //// 1400
/// Margin on the bottom.
public int MaxTop; //// = 10 /*TopSpace*/ + 20 * SeedSize.CurrentHeight; //// 700;
/// The left margin.
public readonly int LeftMargin = 2 * SeedSize.CurrentWidth;
/// The top margin.
public readonly int TopMargin = 2 * SeedSize.CurrentHeight;
///
/// The children
///
private readonly VisualCollection children;
#endregion
#region Fields
///
/// The void handler
///
private static readonly VoidHandler Handler = () => { }; //// 2016/08
///
/// The musical header
///
private MusicalHeader musicalHeader;
#endregion
#region Constructors
/// Initializes a new instance of the class.
public EditorSpace() {
this.SelectionRectangle = new System.Windows.Shapes.Rectangle {
Stroke = Brushes.Black,
HorizontalAlignment = HorizontalAlignment.Left,
VerticalAlignment = VerticalAlignment.Top
};
//// rectangle.Fill = System.Windows.Media.Brushes.SkyBlue;
this.IsDraggingAllowed = true;
this.ResetCells();
TimedPlayer.Singleton.SkipToBar += this.EditorSkipToBar;
this.children = new VisualCollection(this) {
this.CreateDrawingVisual()
};
this.ContentType = EditorContent.Cell;
//// mysize, width, height));
//// this.VisualTextRenderingMode = TextRenderingMode.Grayscale;
//// this.Elements = new List();
}
#endregion
#region Delegates
///
/// Void Handler.
///
private delegate void VoidHandler();
#endregion
#region Public properties
///
/// Gets or sets the number of bars.
///
///
/// The number of bars.
///
public int NumberOfBars { get; set; }
/// Gets or sets the number of lines.
/// The total number of lines.
public int NumberOfLines { get; set; }
///
/// Gets or sets the content of the musical.
///
///
/// The content of the musical.
///
public IMusicalContent MusicalContent { get; set; }
///
/// Gets or sets the type of the content.
///
///
/// The type of the content.
///
public EditorContent ContentType { get; set; }
///
/// Gets or sets a value indicating whether this instance is music editor.
///
///
/// true if this instance is music editor; otherwise, false.
///
public bool IsMusicEditor { get; set; }
///
/// Gets or sets the left scroll.
///
///
/// The left scroll.
///
public double LeftScroll { get; set; }
///
/// Gets or sets the top scroll.
///
///
/// The top scroll.
///
public double TopScroll { get; set; }
#endregion
#region Public properties - Selection
///
/// Gets or sets the selection rectangle.
///
///
/// The selection rectangle.
///
public System.Windows.Shapes.Rectangle SelectionRectangle { get; set; }
///
/// Gets or sets the current editor cell.
///
///
/// The current editor cell.
///
public ContentCell CurrentContentCell { get; set; }
///
/// Gets or sets the current unit.
///
///
/// The current unit.
///
public MusicalElement CurrentElement => this.CurrentContentCell?.Element;
///
/// Gets or sets the current bar number.
///
///
/// The current bar number.
///
[UsedImplicitly]
public int CurrentBarNumber { get; set; }
///
/// Gets or sets a value indicating whether this instance is selection in progress.
///
///
/// true if this instance is selection in progress; otherwise, false.
///
public bool IsSelectionInProgress { get; set; }
///
/// Gets or sets the highlighted cell.
///
///
/// The highlighted cell.
///
public BaseCell SelectedCell { get; set; }
#endregion
#region Public properties - Dragging
///
/// Gets or sets a value indicating whether this instance is dragging allowed.
///
///
/// true if this instance is dragging allowed; otherwise, false.
///
public bool IsDraggingAllowed { get; set; }
#endregion
#region Public properties - Music
/// Gets or sets the get musical header.
/// The get musical header.
public MusicalHeader GetMusicalHeader {
get {
if (this.musicalHeader == null) {
this.musicalHeader = MusicalHeader.GetDefaultMusicalHeader;
this.musicalHeader.NumberOfBars = this.NumberOfBars;
this.musicalHeader.Metric.MetricBeat = 6;
this.musicalHeader.Tempo = 200;
}
return this.musicalHeader;
}
set {
this.musicalHeader = value;
}
}
/// Gets the get harmonic stream.
/// The get harmonic stream.
public HarmonicStream GetHarmonicStream {
get {
var header = this.GetMusicalHeader;
var stream = new HarmonicStream(header);
foreach (var cell in this.BarCells) {
var harmonicBar = new HarmonicBar(header, cell.HarmonicStructure) {
BarNumber = cell.BarIndex + 1
};
stream.HarmonicBars.Add(harmonicBar);
}
return stream;
}
}
#endregion
///
/// Loads the content.
///
/// Content of the given.
/// if set to true [is music].
public void LoadContent(IMusicalContent givenContent, bool givenIsMusic) {
this.MusicalContent = givenContent;
this.musicalHeader = this.MusicalContent.Header;
this.IsMusicEditor = givenIsMusic;
this.MakeCellsFromContent(givenContent, this.ContentType, givenIsMusic);
}
///
/// Copies the paste.
///
/// The code.
public void CopyPaste(char code) {
var c = this.SelectedCell;
var cell = c; //// as ContentCell;
if (cell != null) {
var p = cell.Point;
if (p.BarNumber == 0) {
return;
}
if (code == 'C') {
cell.Copy();
}
if (code == 'V') {
cell.Paste();
}
}
}
#region Private methods - Selection
///
/// Selects all.
///
[UsedImplicitly]
public void SelectAll() {
MusicalPoint point0 = MusicalPoint.GetPoint(0, 1);
MusicalPoint point1 = MusicalPoint.GetPoint(this.NumberOfLines, this.NumberOfBars);
this.MarkSelectedArea(point0, point1, true);
}
#region Private static
///
/// Does the void events.
///
private static void DoVoidEvents()
{
//// Stack Overflow Exception
try
{
//// Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new VoidHandler(() => { }));
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.ApplicationIdle, Handler);
}
catch
{ //// StackOverflowException ex
//// return; //// !?!?!
}
}
#endregion
///
/// Marks the selected area.
///
/// The given point0.
/// The given point1.
/// if set to true [is cell selected].
private void MarkSelectedArea(MusicalPoint givenPoint0, MusicalPoint givenPoint1, bool isCellSelected) { //// Brush color
int minLine = Math.Min(givenPoint0.LineIndex, givenPoint1.LineIndex);
int maxLine = Math.Max(givenPoint0.LineIndex, givenPoint1.LineIndex);
var minBar = Math.Min(givenPoint0.BarNumber, givenPoint1.BarNumber);
var maxBar = Math.Max(givenPoint0.BarNumber, givenPoint1.BarNumber);
var startPoint = MusicalPoint.GetPoint((byte)minLine, minBar);
var endPoint = MusicalPoint.GetPoint((byte)maxLine, maxBar);
var area = new MusicalArea(startPoint, endPoint);
foreach (var cell in this.ContentCells) {
if (area.ContainsPoint(cell.Element.Point)) {
cell.IsSelected = isCellSelected;
}
}
}
///
/// Highlights the bar.
///
/// The bar number.
private void HighlightBar(int barNumber) {
//// MessageBox.Show(barNumber.ToString());
if (barNumber >= 1) {
if (barNumber >= 2) {
var previousCell = this.BarCells[barNumber - 2];
previousCell.IsHighlighted = false;
}
if (barNumber - 1 < this.BarCells.Count) {
var cell = this.BarCells[barNumber - 1];
cell.IsHighlighted = true;
this.InvalidateVisual();
}
}
}
#endregion
#region Listeners
///
/// Editors the skip to bar.
///
/// The sender.
/// The instance containing the event data.
private void EditorSkipToBar(object sender, SkipToBarEventArgs args) {
var dispatcher = this.Dispatcher;
dispatcher?.BeginInvoke(
DispatcherPriority.Background,
(Action)(() => this.HighlightBar(args.BarNumber)));
DoVoidEvents();
//// this.GetButton(args.BarNumber, 0);
}
#endregion
}
}